import React, { useRef } from "react";
import type { Meta, StoryObj } from "@storybook/react-webpack5";

// 导入 Form 组件和相关类型
import Form, { IFormRef } from "./form";
import Item from "./formItem";

// 导入其他组件
import Input, { InputType } from "../Input";
import Button, { ButtonType } from "../Button";

// 导入类型定义
import { CustomRule } from "./useStore";

/**
 * Form 组件的 Storybook 元数据配置
 * 定义了组件在 Storybook 中的基本信息和交互控件
 */
const meta = {
  title: "Components/Form", // 组件在 Storybook 侧边栏中的显示路径
  component: Form, // 关联的 React 组件
  subcomponents: { Item: Item }, // 子组件
  parameters: {
    layout: "centered", // 布局方式：居中显示
    docs: {
      source: {
        type: "code", // 显示源代码
      },
    },
  },
  tags: ["autodocs"], // 自动生成文档标签
  decorators: [
    // 装饰器：设置故事容器的宽度
    (Story) => (
      <div style={{ width: "550px" }}>
        <Story />
      </div>
    ),
  ],
  argTypes: {
    // 初始值配置
    initialValues: {
      control: "object", // 使用对象控件
      description: "表单初始值", // 控件描述
    },
    // 表单提交事件处理
    onFinish: { action: "submitted" }, // 记录提交事件的动作
    // 表单提交失败事件处理
    onFinishFailed: { action: "submit-failed" }, // 记录提交失败事件的动作
  },
} satisfies Meta<typeof Form>;

export default meta;

/**
 * Story 类型定义
 * 基于元数据生成的 Story 类型，用于类型安全的 Story 定义
 */
type Story = StoryObj<typeof meta>;

/**
 * 基本登录表单示例
 * 展示最简单的表单使用场景
 */
export const BasicForm: Story = {
  name: "基本登录表单", // 中文翻译名称
  render: (args) => (
    <Form {...args}>
      {/** 用户名表单项 */}
      <Item
        label="用户名"
        name="name"
        rules={[{ type: "string", required: true, min: 3 }]}
      >
        <Input />
      </Item>

      {/** 密码表单项 */}
      <Item
        label="密码"
        name="password"
        rules={[{ type: "string", required: true, min: 3, max: 8 }]}
      >
        <Input type={InputType.password} />
      </Item>

      {/** 提交按钮区域 */}
      <div className="viking-form-submit-area">
        <Button type="submit" btnType={ButtonType.primary}>
          登录
        </Button>
      </div>
    </Form>
  ),
};

/**
 * 注册表单示例
 * 展示支持多种 FormItem 组件的复杂表单
 */
export const RegistrationForm: Story = {
  name: "注册表单", // 中文翻译名称
  args: {
    initialValues: {
      agreement: false, // 协议同意状态初始值
    },
  },
  render: (args) => (
    <Form {...args}>
      {/** 邮箱表单项 */}
      <Item
        label="邮件"
        name="email"
        rules={[{ type: "email", required: true }]}
      >
        <Input />
      </Item>

      {/** 密码表单项 */}
      <Item
        label="密码"
        name="password"
        rules={[{ type: "string", required: true, min: 3, max: 8 }]}
      >
        <Input type={InputType.password} />
      </Item>

      {/**
       * 协议同意表单项
       * 使用 checkbox，需要特殊的值处理
       */}
      <div
        className="agreement-section"
        style={{ display: "flex", justifyContent: "center" }}
      >
        <Item
          name="agreement"
          rules={[{ type: "enum", enum: [true], message: "请同意协议" }]} // 枚举验证
          getValueFromEvent={(e) => e.target.checked} // 从事件中获取选中状态
          valuePropName="checked" // 值属性名
        >
          <input type="checkbox" />
        </Item>
        <span className="agree-text">
          注册即代表你同意<a href="#">用户协议</a>
        </span>
      </div>

      {/** 提交按钮区域 */}
      <div className="viking-form-submit-area">
        <Button type="submit" btnType={ButtonType.primary}>
          注册
        </Button>
      </div>
    </Form>
  ),
};

/**
 * 自定义验证规则：确认密码验证
 * 包含基本验证和异步自定义验证
 */
const confirmRules: CustomRule[] = [
  // 基本验证规则：必填、最小长度3、最大长度8
  { type: "string", required: true, min: 3, max: 8 },

  // 自定义异步验证规则：确认密码必须与密码一致
  ({ getFieldValue }) => ({
    asyncValidator(rule, value) {
      console.log("the value", getFieldValue("password")); // 调试日志：密码字段值
      console.log(value); // 调试日志：当前字段值

      return new Promise((resolve, reject) => {
        // 验证逻辑：确认密码必须与密码一致
        if (value !== getFieldValue("password")) {
          reject("The two passwords that you entered do not match!"); // 验证失败
        }

        // 模拟异步验证延迟
        setTimeout(() => {
          resolve(); // 验证成功
        }, 1000);
      });
    },
  }),
];

/**
 * 完整表单示例
 * 展示自定义规则和表单实例调用的高级用法
 */
export const FullForm: Story = {
  name: "完整表单", // 中文翻译名称
  render: (args) => {
    // 表单引用，用于调用表单实例方法
    const ref = useRef<IFormRef>(null);

    // 重置表单处理函数
    const resetAll = () => {
      console.log("form ref", ref.current); // 调试日志：表单引用
      ref.current?.resetFields(); // 调用表单重置方法
    };

    return (
      <Form
        {...args}
        ref={ref}
        onFinish={(result) => {
          console.log(result); // 调试日志：表单提交结果
        }}
        onFinishFailed={(values, errors) => {
          console.log("finish failed", values, errors); // 调试日志：表单提交失败信息
        }}
      >
        {/** 用户名表单项 */}
        <Item
          label="用户名"
          name="name"
          rules={[{ type: "string", required: true, min: 3 }]}
        >
          <Input />
        </Item>

        {/** 密码表单项 */}
        <Item
          label="密码"
          name="password"
          rules={[{ type: "string", required: true, min: 3, max: 8 }]}
        >
          <Input type={InputType.password} />
        </Item>

        {/** 确认密码表单项 - 使用自定义验证规则 */}
        <Item label="重复密码" name="confirmPwd" rules={confirmRules}>
          <Input type={InputType.password} />
        </Item>

        {/** 协议同意表单项 */}
        <div
          className="agreement-section"
          style={{ display: "flex", justifyContent: "center" }}
        >
          <Item
            name="agreement"
            valuePropName="checked" // 值属性名
            getValueFromEvent={(e) => e.target.checked} // 从事件中获取选中状态
            rules={[{ type: "enum", enum: [true], message: "请同意协议" }]} // 枚举验证
          >
            <input type="checkbox" />
          </Item>
          <span className="agree-text">
            注册即代表你同意<a href="#">用户协议</a>
          </span>
        </div>

        {/** 按钮区域 */}
        <div className="viking-form-submit-area">
          <Button type="submit" btnType={ButtonType.primary}>
            登录
          </Button>
          <Button type="button" onClick={resetAll}>
            重置
          </Button>
        </div>
      </Form>
    );
  },
};
